home *** CD-ROM | disk | FTP | other *** search
- /*
- * xsgll.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * XSGLL
- *
- * construct segm adj lists (SAL) and segm group lists (SGL)
- * by invoking manipulation routines for doubly linked lists;
- * the data item associated with a particular link (node) of a list
- * is defined as struct itemtype (here: Segmtype, see below);
- *
- * one SAL, SAL<i>, is constructed (in the form of a doubly linked
- * list) for each segment <i> in the image, obtained from a Wall-Damielsson
- * linear approximation and stored in a file of type .seg, and entered
- * into an array sall[] of SALs;
- * for convenience of subsequent construction of SGLs, each SAL
- * contains segments in the order of decreasing inverse overlap, pji;
- * the reference element <i> (whose pji is set to 999.0) is placed at
- * the top; by setting an approriate switch (in sall.c), SALs may also be
- * constructed in the order of increasing dij, (with dij for the
- * reference segment set to 0.0); in that case, each list represents
- * the (forward and backward) segm adjacency list of segment <i>;
- *
- * the segm group list is constructed by contration of SALs
- * and ordered according to dij:
- * segments j for which dij < 0 will be precede i in the list (b-SAL)
- * segments j for which dij > 0 will be follow i in the list (f-SAL)
- *
- * note:
- * -->short int and int are assumed to be identical (16 bits)!!
- *
- * -->improvements are possible to substantially reduce the amount
- * of dynamically allocated memory required for SAL and SGL storage:
- * in multiple copies of each segment entered in SALs, keep only
- * the segment index, e.g. <j>, and the pertinent mutual parameters
- * referring to the reference segment <i>, i.e., dij, pij, pji;
- * this reduces the amount of memory required per list node from
- * currently 12+32 bytes to 12+14 bytes;
- * initialize only non-empty SGLs of which there are only n_sgl<<n_segm;
- *
- * note:
- * to reduce amount of dynamically allocated memory in the way indicated
- * in the note above, the present version of xsgll and associated modules
- * maintain two segment structures (defined in sgl.h):
- * the first ( struct Segm ) contains data relating to only a single segment
- * (endpoints, slope, segm. index and line index), while the second structure
- * ( struct Segmtype ) serves to store information relating to pairs of
- * segments, relevant to SAL and SGL construction
- * (pij, pji, dij, segm. index, sgl_level, SalStat);
- *
- * the original and conceptually preferable version of the code maintains only
- * one structure referring to segments;
- * see: lsgl.h, lxsgll.c,
- * lsgll.c, lsall.c, ltestsegm.c, lsgl_to_poly.c,lsgl_stats.c
- *
- */
-
- #include "xsgll.h"
-
- #define MS_TESTSET 13 /* select one of two test sets */
- #define LRM_TESTSET 11 /* contained in testsegm.seg */
- #define TOTAL_SEG LRM_TESTSET
-
- #undef DEBUG
- #undef DBG_MEM
-
- #undef ECHO_INPUT
- #undef SHOW_VERT
- #undef SAVE_VERT /* save cluster vertex coordinates */
-
-
-
- /* default values for thresholds used for SAL and SGL construction */
- /*
- * segment pairs are processed (in sall.c) if their relative orientation
- * differs by less than ANGL_THRESH, their overlap pij exceeds OVLP_THRESH
- * and their perpendicular distance (see sall.c, prlpar.c) does not
- * exceed D_MAX
- */
- #define ANGL_THRESH 10.0 /* threshold in degrees */
- /* tg(th2-th1) is comp. to */
- /* slp_thresh = tg(ANGL_THRESH) */
- #define OVLP_THRESH 50.0 /* normalized to vary between 0.0 amd 100.0 */
- #define D_MAX 50.0 /* in pixels */
-
- #define N_BINS 10 /* number of bins in cluster area histogram */
-
-
- #define NO_DISPLAY -1
- #define TERSE 0
- #define VERBOSE 1
-
- #define NA_MAX 128 /* max no allowed vertices in ph.c */
-
- /*
- * global variables
- */
- int loop_switch = 1; /* enable/disable loop over poly approx */
- int hull_switch = 1; /* enable/disable evaluation of hull eval */
- int n_ap_max = NA_MAX;
- extern char *optarg;
- extern int optind, opterr;
-
- int DRAW_MODE = 1; /* 1: overwrite existing image */
- /* 3: XOR, i. e. overlay output onto img */
- int WRITE_FILE = 0;
- int DISP_MODE = NO_DISPLAY; /* VERBOSE, TERSE or NO_DISPLAY */
- int TEST_INPUT = 0;
- int INPUT = 1;
- int COLOR_CODE = 0; /* when set, segm clusters are color coded */
- /* acc to segm normal dirn (gpoly_hull.c) */
- int DISPL_CONV_HULL = 1; /* when set, display convex hull */
- int MERGE = 1; /* when set, merge segments after SGL construction */
-
-
- /*
- * initialize list parameters
- *
- * note: matching function is set by call to llsetmatch() in code as needed
- */
- void
- init_sall (struct linklist *segm_adj_list)
- {
-
- llzero (segm_adj_list); /* init empty list */
- llsetsize (sizeof (struct Segmtype), segm_adj_list);
- }
-
-
- /*
- * initialize list parameters
- *
- * note: matching function is set by call to llsetmatch() in code as needed
- */
- void
- init_sgll (struct linklist *segm_group_list)
- {
-
- llzero (segm_group_list); /* init empty list */
- llsetsize (sizeof (struct Segmtype), segm_group_list);
- }
-
- /*
- * deallocate memory occupied by links in a list
- */
- int
- rm_llistlink (struct linklist *list)
- {
- int link_count;
-
- link_count = 0;
- llhead (list);
- do {
- lldelete (list);
- link_count++;
-
- } while (list->listlength != 0);
-
- return (link_count);
- }
-
-
-
- /*
- * display list (terse version)
- */
- void
- tshow_segm_list (struct linklist *list, int index)
- {
- struct Segmtype *segm;
- int isegm = 0;
-
- printf ("\n...list<%d>\n", index);
- llhead (list);
- if (ll_length (list) != 0) { /* list not empty */
- do {
- segm = (struct Segmtype *) list->clp->item;
- printf (" %3d", segm->segm_ind);
- if ((isegm + 1) % 12 == 0) {
- isegm = 0;
- printf ("\n");
- }
- } while (llnext (list) == True);
- }
- else
- printf (" list empty\n");
- }
-
- /*
- * display list
- */
- void
- show_segm_list (struct linklist *list, int index)
- {
- struct Segmtype *segm;
-
- printf ("\n...list <%d>\n", index);
- llhead (list);
- if (ll_length (list) != 0) { /* list not empty */
- do {
- segm = (struct Segmtype *) list->clp->item;
- printf (" segm: %3d", segm->segm_ind);
- printf (" d(%2d,%2d): %6.2f",
- index, segm->segm_ind, segm->dij);
- printf ("\tp(%2d,%2d): %6.2f",
- index, segm->segm_ind, segm->pij);
- printf (" p(%2d,%2d): %6.2f",
- segm->segm_ind, index, segm->pji);
- printf (" SGL lev: %d", segm->sgl_level);
- printf ("\n");
- } while (llnext (list) == True);
- }
- else
- printf (" list empty\n");
- }
-
-
-
- /*
- * evaluate slope of linear segment
- */
- float
- fslope (struct spoint pt1, struct spoint pt2)
- {
- double m;
- double max_slope = 500.0; /* max. poss. slope */
- int x1, y1, x2, y2;
-
- x1 = (int) pt1.x;
- y1 = (int) pt1.y;
- x2 = (int) pt2.x;
- y2 = (int) pt2.y;
-
- if ((int) (x2 - x1) == 0) {
- if ((int) (y2 - y1) == 0)
- m = 0.0;
- else
- m = max_slope;
- }
- else
- m = ((double) (y2 - y1)) / ((double) (x2 - x1));
-
- return ((float) m);
- }
-
-
-
-
- /*
- * read first line in data file to determine size of record
- */
- void
- get_record_size (FILE * file, int *n_segm, int *xmax, int *ymax)
- {
- int retval;
-
- if (((retval = fscanf (file, "%d %d %d", n_segm, xmax, ymax)) != 3) || (retval == EOF)) {
- printf ("wrong input file format!\n");
- exit (1);
- }
- }
-
-
- /*
- * read segment data from formatted data file (generally of type .seg)
- * written by pcctoseg.c; first column contains segment index.
- */
- void
- init_segm (FILE * fp, int n_segm, struct Segm *segm)
- {
- int i;
- int retval;
- float skip_slope;
-
-
- for (i = 0; i < n_segm; i++) {
- retval = fscanf (fp, "%4d %3d %3d %3d %3d %f %3d",
- &((segm + i)->segm_ind),
- &((segm + i)->ptO.x), &((segm + i)->ptO.y),
- &((segm + i)->ptF.x), &((segm + i)->ptF.y),
- &skip_slope, &((segm + i)->line_ind));
-
- /*
- * recompute slope with function internal to this module
- */
- (segm + i)->slope = (float) slope (&(segm + i)->ptO, &(segm + i)->ptF);
-
- }
- }
-
-
-
-
- /*
- * gprintf() functions:
- * write to std output and, if option WRITE_FILE set, to file wbuf (stream)
- */
- void
- gprintf (FILE * fpOut, char *fmt,...)
- {
- va_list arg_ptr;
-
- va_start (arg_ptr, fmt);
- vprintf (fmt, arg_ptr);
- if (WRITE_FILE == 1)
- vfprintf (fpOut, fmt, arg_ptr);
- va_end (arg_ptr);
-
- }
-
-
-
- /*
- * error message
- */
- void
- exitmess (char *prompt, int status)
- {
- printf (prompt);
- printf ("\n");
-
- exit (status);
- }
-
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s infile outimg [-t] [-w] [-a ang_thresh][-p ovlp_thresh]\n", progname);
- printf (" [-d d_max] [-m] [-o] [-c] [-h] [-L]\n");
- printf ("\n%s constructs segm adj lists (SAL) and segment group lists (SGL)\n", progname);
- printf ("given an input file containing line segment data; writes output\n");
- printf ("data into file and creates image containing line segment clusters\n\n");
- printf ("ARGUMENTS:\n");
- printf (" infile: input filename (.seg) (ASCII)\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -t: employ test data in test_segm.c\n");
- printf (" -w: write sgl parameters and stats to file fn.sgl\n");
- printf ("-a angl_thresh: set angle threshold - default: 10 deg\n");
- printf ("-p ovlp_thresh: set ovlp_thresh (0 <= pij <= 100) - default: 50\n");
- printf (" -d d_max: set maximum dist between segments - default: 50 pixels\n");
- printf (" -m: do not merge segments after SGL constr\n");
- printf (" -o: overlay topological features onto image\n");
- printf (" -c: display segment clusters\n");
- printf (" -h: do not display conv hull, only orig. polygon\n");
- printf (" -L: print Software License for this module\n");
- exit (1);
- }
-
-
- void
- main (int argc, char *argv[])
- {
- FILE *file, *fpOut;
- static char *buf =
- {"inpsegm.seg"}; /* default input file name */
- static char *wsuffix =
- {".sgl"}; /* suffix for output file name */
- static char wbuf[13];
- int ich, is;
-
- /* threshold variables */
- int i_arg;
- float angl_thresh = (float) ANGL_THRESH;
- float ovlp_thresh = (float) OVLP_THRESH;
- float d_max = (float) D_MAX;
-
- /* SAL */
- struct linklist *sall; /* array of segm adj lists */
- #ifdef DEBUG
- struct linklist *csall; /* ptr to current SAL */
- #endif
- struct Segm *inSegm; /* sample input */
- int n_segm;
- int n_sall = 0;
- int i;
-
- /* SGL */
- struct linklist *sgll; /* array of segm group lists */
- struct linklist *csgll; /* ptr to current SGL */
- int n_sgl = 0;
- int rm_link;
-
- /* vertices and convex hull */
- struct spoint *poly_vert, *v_ap; /* ptr to (cycl) poly */
- int *x_vert, *y_vert;
- int iv, nv, nvpp;
- long lnv;
- struct spoint *hullctr;
- int xhullc, yhullc;
- double av_dirn = (double) 0.0; /* average directn of SGL segm */
- float s_nem, *clust_dirn;
-
- float maxlen, maxwidth;
- float *asp_ratio; /* eccentricity of SGL */
- int *ex_hist;
- float min_asp_ratio, max_asp_ratio, ex_bin_width;
-
- int min_cluster_area, max_cluster_area, area_bin_width;
- int ibin, tot_number;
- int *clust_area, *area_hist;
- int *hull_area;
-
- int *clust_lsz, *lsz_hist;
- int min_lsz, max_lsz, nlsz_bins;
-
-
- struct Bdy bd, *bdp = &bd; /* hsbaird's boundary struct */
- double tot_phi = (double) -8.0;
-
- /* graphics */
- Image *ip;
- int xmax = 0;
- int ymax = 0;
-
- /*
- * cmd line options ( see usage() ):
- */
- static char *optstring = "twa:p:d:mochL";
-
-
- /*
- * parse command line
- */
- optind = 3;
- opterr = 1; /* give error messages */
-
- if (argc < 3)
- usage (argv[0]);
-
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- switch (i_arg) {
-
- case 't':
- printf ("\n...option %c: ", i_arg);
- printf ("employ test data in test_segm.c\n");
- n_segm = TOTAL_SEG;
- TEST_INPUT = 1;
- INPUT = 0;
- break;
- case 'w':
- printf ("\n...option %c: ", i_arg);
- WRITE_FILE = 1;
- break;
- case 'a':
- printf ("\n...option %c: ", i_arg);
- printf ("set angle threshold to: %f\n",
- angl_thresh = (float) atof (optarg));
- break;
- case 'p':
- printf ("\n...option %c: ", i_arg);
- printf ("set overlap threshold to: %f\n",
- ovlp_thresh = (float) atof (optarg));
- break;
- case 'd':
- printf ("\n...option %c: ", i_arg);
- printf ("set max segm-to-segm dist to: %f\n",
- d_max = (float) atof (optarg));
- break;
- case 'm':
- printf ("\n...option %c:", i_arg);
- printf (" do not merge segments after SGL construction\n");
- MERGE = 0;
- break;
- case 'o':
- printf ("\n...option %c:", i_arg);
- printf (" overlay output on img in buf 1\n");
- DRAW_MODE = 3;
- break;
- case 'c':
- printf ("\n...option %c:", i_arg);
- printf (" display segment clusters\n");
- COLOR_CODE = 1;
- break;
- case 'h':
- printf ("\n...option %c:", i_arg);
- printf (" do not display convex hull, only original polygon\n");
- DISPL_CONV_HULL = 0;
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- printf ("\n...unknown condition encountered\n");
- exit (1);
- break;
- }
- }
-
-
- if (!TEST_INPUT) {
- printf ("read segment data from file %s\n", buf = argv[1]);
- /* get size of data set from file */
- if ((file = fopen (buf, "r")) == NULL) {
- printf ("\n...could not open file %s\n", buf);
- exit (1);
- }
- /* initialize size variables */
- get_record_size (file, &n_segm, &xmax, &ymax);
- if (n_segm > MAX_REC_SIZE) {
- printf ("\n...record size of %d exceeds limit of %d\n", n_segm, MAX_REC_SIZE);
- exit (1);
- }
-
- /* construct output file name */
- ich = 0;
- while ((*(wbuf + ich) = *(buf + ich)) != '.')
- ich++;
- for (is = 0; is < 4; is++)
- *(wbuf + (ich) + is) = *(wsuffix + is);
-
- if (WRITE_FILE) {
- if ((fpOut = fopen (wbuf, "w")) == NULL) {
- printf ("\n...cannot open %s for writing\n", wbuf);
- exit (1);
- }
- gprintf (fpOut, "logging SGL params in file %s\n", wbuf);
- }
- }
-
-
- #ifdef DBG_MEM
- gmod_logfile (1); /* turn on(1)/off(0) gmod log file */
- #endif
-
- /*
- * display parameter settings employing global printf function;
- * open log file
- */
- gprintf (fpOut, "\nthreshold settings:\n");
- gprintf (fpOut, " ANGL_THRESH = %f slp_thresh = %f\n",
- angl_thresh, tan (angl_thresh * (2.0 * PI / 360.0)));
- gprintf (fpOut, " OVLP_THRESH = %f\n", ovlp_thresh);
- gprintf (fpOut, " DIST_THRESH = %f\n", d_max);
-
-
- /*
- * memory allocation
- */
- if ((inSegm = (struct Segm *) calloc (n_segm, sizeof (struct Segm))) == NULL)
- exitmess ("can't allocate mem for struct Segm *inSegm", 1);
- if ((sall = (struct linklist *) calloc (n_segm, sizeof (struct linklist))) == NULL)
- exitmess ("can't allocate mem for struct linklist *sall", 1);
- if ((sgll = (struct linklist *) calloc (n_segm, sizeof (struct linklist))) == NULL)
- exitmess ("can't allocate mem for struct linklist *sgll", 1);
-
-
- /*
- * fetch segment data
- */
- if (TEST_INPUT == 1) {
- printf ("\n...initialize test segments\n");
- init_testsegm (inSegm, n_segm);
- ymax = HEIGHT;
- xmax = WIDTH;
- }
- else if (INPUT == 1) {
- gprintf (fpOut, "input file for segment data: %s\n", buf);
- init_segm (file, n_segm, inSegm);
- fclose (file);
- }
-
- /*
- * initialize graphics
- */
- ip = ImageAlloc ((long) ymax, (long) xmax, BPS);
-
-
- #ifdef ECHO_INPUT
- printf ("\n...segment data, asread in from file:\n");
- for (i = 0; i < n_segm; i++) {
- printf ("%4d %3d %3d %3d %3d\n",
- (inSegm + i)->segm_ind,
- (inSegm + i)->ptO.x, (inSegm + i)->ptO.y,
- (inSegm + i)->ptF.x, (inSegm + i)->ptF.y);
- }
- #endif
-
- printf ("\n...initialize %d empty Segm Adj Lists (SAL)\n", n_segm);
- for (i = 0; i < n_segm; i++)
- init_sall (sall + i);
-
- #ifdef DEBUG
- csall = sall + 0;
- printf ("\n...structure parameters for segm adj list number 0:\n");
- printf ("sizeof(struct linklist): %d\n", sizeof (struct linklist));
- printf (" item length: %d\n", csall->itemlength);
- printf (" cur list length: %d\n", csall->listlength);
- #endif
-
-
- printf ("...construct SAL for each of %d segments\n", n_segm);
- printf (" (in the form of a doubly linked list of segments)\n");
- n_sall = construct_sall (sall, inSegm, n_segm,
- angl_thresh, ovlp_thresh, d_max);
-
- /*
- * display results
- */
- printf ("\n...done with construction of pji-ordered SAL:\n");
-
-
- if (DISP_MODE == VERBOSE)
- for (i = 0; i < n_segm; i++)
- show_segm_list (sall + i, i);
- else if (DISP_MODE == TERSE)
- for (i = 0; i < n_segm; i++)
- tshow_segm_list (sall + i, i);
-
-
- /*
- * SGL construction
- */
- printf ("\n...initialize %d empty Segm Group Lists (SGL)\n", n_segm);
- for (i = 0; i < n_segm; i++)
- init_sgll (sgll + i);
-
-
- #ifdef DEBUG
- csgll = sgll + 0;
- printf ("\n...structure parameters for segm adj list number 0:\n");
- printf (" item length: %d\n", csgll->itemlength);
- printf (" cur list length: %d\n", csgll->listlength);
- #endif
-
- n_sgl = construct_sgll (inSegm, sall, sgll, n_segm, (double) ovlp_thresh);
-
- /*
- * display results
- */
- printf ("\n...done with construction of dij-ordered SGL:\n");
-
- gprintf (fpOut, "\tnumber of SGLs: %3d\n", n_sgl);
- gprintf (fpOut, "\t ACCEPT_LEVEL: %3d\n", ACCEPT_LEVEL);
- gprintf (fpOut, "\t min sz for proc: %3d\n", MIN_SGL_SIZE);
-
- if (DISP_MODE == VERBOSE)
- for (i = 0; i < n_segm; i++)
- show_segm_list (sgll + i, i);
- else if (DISP_MODE == TERSE)
- for (i = 0; i < n_segm; i++)
- tshow_segm_list (sgll + i, i);
-
-
- /*
- * construct an ordered, cyclic sequence of vertices from the
- * endpoints of the segments in a segm group list; handle each
- * SGL in turn, skipping those containing less than MIN_SGL_SIZE segments;
- *
- * there will be n_sgl <= n_sall <= n_segm (closed) polygons, each containing
- * nv+1 points: nv thus represents the number of distinct vertices!
- */
- #ifdef DEBUG
- printf ("\n...size of struct Bdy: %d\n", sizeof (struct Bdy));
- #endif
-
- if ((clust_dirn = (float *) calloc (n_segm, sizeof (float))) == NULL)
- exitmess ("can't allocate mem for clust_dirn", 1);
-
- if ((clust_area = (int *) calloc (n_segm, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for clust_area", 1);
-
- if ((clust_lsz = (int *) calloc (n_segm, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for clust_lsz", 1);
-
- if ((hull_area = (int *) calloc (n_segm, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for hull_area", 1);
-
- if ((asp_ratio = (float *) calloc (n_segm, sizeof (float))) == NULL)
- exitmess ("can't allocate mem for asp_ratio", 1);
-
-
-
- min_cluster_area = 10000;
- max_cluster_area = 0;
- min_asp_ratio = (float) 1000.0;
- max_asp_ratio = (float) 0.0;
- min_lsz = 1000;
- max_lsz = 0;
- n_sgl = 0;
- for (i = 0; i < n_segm; i++)
- *(clust_dirn + i) = (float) 999.0;
-
- for (i = 0; i < n_segm; i++) { /* loop over SGLs */
- csgll = sgll + i;
- if ((nv = 2 * csgll->listlength) >= 2 * MIN_SGL_SIZE) {
- n_sgl++; /* count SGLs of sufficient length */
-
- if ((poly_vert = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
- exitmess ("can't allocate mem for poly_vert", 1);
-
- if ((v_ap = (struct spoint *) calloc (nv + 1, sizeof (struct spoint))) == NULL)
- exitmess ("\n...mem allocation for v_ap failed\n", 1);
-
- if ((x_vert = (int *) calloc (nv + 1, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for x_vert", 1);
- if ((y_vert = (int *) calloc (nv + 1, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for y_vert", 1);
-
-
- /*
- * construct polygon (closed array of nv+1 vertices) and
- * determine average segment orientation; note that merging
- * of segments after SGL construction will result in the elimination
- * of segments; for each segment deleted from the SGL, the number of
- * vertices must be diminished by two
- */
- nvpp = nv + 1;
- av_dirn = construct_va (inSegm, csgll, &nvpp, poly_vert);
- *(clust_dirn + i) = (float) av_dirn;
- nv = nvpp - 1;
-
- /*
- * evaluate cluster longitudinal size (no of segments) and aspect ratio,
- * a cluster being defined as the set of linear segments in a SGL
- */
- *(clust_lsz + i) = nv / 2;
- if (*(clust_lsz + i) > max_lsz)
- max_lsz = *(clust_lsz + i);
- if (*(clust_lsz + i) < min_lsz)
- min_lsz = *(clust_lsz + i);
-
- *(asp_ratio + i) = eccentr (inSegm, csgll,
- &maxlen, &maxwidth);
- if (*(asp_ratio + i) > max_asp_ratio)
- max_asp_ratio = *(asp_ratio + i);
- if (*(asp_ratio + i) < min_asp_ratio)
- min_asp_ratio = *(asp_ratio + i);
-
-
- /*
- * collect cluster areas to be used in histogram evaluation and
- * determine minimum and maximum cluster areas
- */
- for (iv = 0; iv <= nv; iv++) {
- *(x_vert + iv) = (poly_vert + iv)->x;
- *(y_vert + iv) = (poly_vert + iv)->y;
- }
-
- *(clust_area + i) = zero_moment (nv, x_vert, y_vert);
- if (*(clust_area + i) > max_cluster_area)
- max_cluster_area = *(clust_area + i);
- if (*(clust_area + i) < min_cluster_area)
- min_cluster_area = *(clust_area + i);
-
- /*
- * display geometrical parameters
- */
- #ifdef DEBUG
- gprintf (fpOut, "\ngeometr prop of cluster %d:\n", i);
- gprintf (fpOut, " no of segments: %d\n",
- csgll->listlength);
- gprintf (fpOut, " area = %d\n", *(clust_area + i));
- gprintf (fpOut, " length = %6.2f, width = %6.2f\n",
- maxlen, maxwidth);
- gprintf (fpOut, " asp_ratio = %6.2f\n", *(asp_ratio + i));
- gprintf (fpOut, " avrg_dirn = %6.2f\n", av_dirn);
- #endif
-
-
- #ifdef SHOW_VERT
- printf ("\n...ordered vertex array for SGL<%d>\n", i);
- printf (" n_vertex: %d\n", nv);
- printf (" avrg slope: %lf\n", av_dirn);
- for (iv = 0; iv <= nv; iv++)
- printf (" (%d, %d)\n",
- (poly_vert + iv)->x, (poly_vert + iv)->y);
-
- #endif
- #ifdef SAVE_VERT
- gprintf (fpOut, "\n...ordered vertex array for SGL<%d>\n", i);
- gprintf (fpOut, " n_vertex: %d\n", nv);
- gprintf (fpOut, " avrg slope: %lf\n", av_dirn);
- for (iv = 0; iv <= nv; iv++)
- gprintf (fpOut, " (%d, %d)\n",
- (poly_vert + iv)->x, (poly_vert + iv)->y);
- #endif
-
-
-
- /*
- * construct convex hull of cluster
- */
- lnv = (long) nv;
- fill_bdy_structure (bdp, poly_vert, lnv, tot_phi);
- hullctr = poly_hull_tol (bdp, v_ap, av_dirn, hull_area + i, (float) 0.0, ip, WHITE);
-
- xhullc = hullctr->x;
- yhullc = hullctr->y;
-
- /*
- * deallocate memory
- */
- free (x_vert);
- free (y_vert);
- free (poly_vert);
- free (v_ap);
-
- free (bdp->hpp); /* allocated in poly_approx.c */
- free (bdp->ap); /* allocated in poly_approx.c */
- free (bdp->v); /* allocated in poly_edge.c */
- }
- }
-
- if (!n_sgl) {
- printf ("No clusters found to process\nExiting!\n");
- exit (0);
- }
-
-
-
- /*
- * evaluate SGL (cluster) longitudinal size (no of segments) histogram
- */
- nlsz_bins = max_lsz - min_lsz + 1;
- if ((lsz_hist = (int *) calloc (nlsz_bins, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for lsz_hist", 1);
- find_lsz_hist (n_segm, clust_lsz, lsz_hist, nlsz_bins, min_lsz);
-
- tot_number = 0;
- gprintf (fpOut, "\nhistogram of cluster longit. sizes:\n");
- gprintf (fpOut, " maximum no of segm: %d\n", max_lsz);
- gprintf (fpOut, " minimum no of segm: %d\n", min_lsz);
- for (ibin = 0; ibin < nlsz_bins; ibin++) {
- gprintf (fpOut, " %3d ", *(lsz_hist + ibin));
- if ((ibin + 1) % 10 == 0)
- gprintf (fpOut, "\n");
-
- tot_number += *(lsz_hist + ibin);
- }
- gprintf (fpOut, "\n");
-
- /*
- * evaluate SGL (cluster) aspect ratio (eccentricity: ex ) histogram
- */
- ex_bin_width = (max_asp_ratio - min_asp_ratio) / (float) N_BINS;
- if ((ex_hist = (int *) calloc (N_BINS, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for ex_hist", 1);
- find_ex_hist (n_segm, asp_ratio, ex_hist, ex_bin_width, min_asp_ratio);
-
- tot_number = 0;
- gprintf (fpOut, "\nhistogram of cluster aspect ratios:\n");
- gprintf (fpOut, " maximum asp ratio: %f\n", max_asp_ratio);
- gprintf (fpOut, " minimum asp ratio: %f\n", min_asp_ratio);
- gprintf (fpOut, " ex_bin_width: %f\n", ex_bin_width);
- for (ibin = 0; ibin < N_BINS; ibin++) {
- gprintf (fpOut, " %3d ", *(ex_hist + ibin));
- tot_number += *(ex_hist + ibin);
- }
- gprintf (fpOut, "\n");
-
- /*
- * evaluate SGL (cluster) area histogram
- */
- area_bin_width = (max_cluster_area - min_cluster_area) / N_BINS;
- if ((area_hist = (int *) calloc (N_BINS, sizeof (int))) == NULL)
- exitmess ("can't allocate mem for area_hist", 1);
- find_area_hist (n_segm, clust_area, area_hist,
- area_bin_width, min_cluster_area);
-
- tot_number = 0;
- gprintf (fpOut, "\nhistogram of cluster areas:\n");
- gprintf (fpOut, " maximum area: %d\n", max_cluster_area);
- gprintf (fpOut, " minimum area: %d\n", min_cluster_area);
- gprintf (fpOut, " area_bin_width: %d\n", area_bin_width);
- for (ibin = 0; ibin < N_BINS; ibin++) {
- gprintf (fpOut, " %3d ", *(area_hist + ibin));
- tot_number += *(area_hist + ibin);
- }
- gprintf (fpOut, "\n");
-
- /*
- * evaluate nematic order parameter for ensemble of clusters
- */
- s_nem = nematic_op (n_sgl, n_segm, clust_dirn);
- gprintf (fpOut, "\nnematic order parameter: S = %6.2f\n", s_nem);
-
-
- free (asp_ratio);
- free (ex_hist);
- free (clust_area);
- free (area_hist);
- free (clust_lsz);
- free (lsz_hist);
- free (clust_dirn);
-
- free (hull_area);
- /*
- * deallocate memory assigned to lists
- */
- printf ("\n...deallocating memory for linked lists\n");
- printf (" SALs:\n");
- for (i = 0; i < n_segm; i++) {
- if ((sall + i)->listlength != 0) {
- rm_link = rm_llistlink (sall + i);
- #ifdef DBG_MEM
- printf (" for SAL<%d>: %d links removed\n",
- i, rm_link);
- #endif
- }
- }
- printf (" SGLs\n");
- for (i = 0; i < n_segm; i++) {
- if ((sgll + i)->listlength != 0) {
- rm_link = rm_llistlink (sgll + i);
- #ifdef DBG_MEM
- printf (" for SGL<%d>: %d links removed\n",
- i, rm_link);
- #endif
- }
- }
-
- free (inSegm); /* free array of input segments */
- free (sall);
- free (sgll);
-
- if (WRITE_FILE == 1)
- fclose (fpOut);
- ImageOut (argv[2], ip);
-
- #ifdef DBG_MEM
- printf ("\n...no of bytes still in use: %d\n", gmod_inuse ());
- gmod_logfile (0);
- #endif
- }
-